use std::sync::Arc;

use crate::classfile;

use super::{ConstantPool, class::Class};

// 类符号引用
#[derive(Clone)]
pub struct ClassRef {
    cp: Arc<ConstantPool>,
    class_name: String, // 类的完全限定名
    class: Option<Arc<Class>>, // 缓存解析后的类结构体
    // cp_symref ↑
}

// cp_symref
impl ClassRef {
    pub fn resolved_class(&mut self) -> Arc<Class> {
        // class为空要解析class
        if self.class.is_none() {
            self.resolve_class_ref();
        }
        self.class.as_ref().unwrap().clone()
    }

    // 类符号引用解析
    fn resolve_class_ref(&mut self) {
        let d = self.cp.get_class();
        let loader = d.get_class_loader().unwrap();
        // TODO class_name 用的clone，后续调整标记
        let c = loader.lock().unwrap().load_class(self.class_name.clone());
        if !c.is_accessible_to(d.as_ref()) {
            panic!("java.lang.IllegalAccessError");
        }
        self.class = Some(c);
    }
}

impl ClassRef {
    pub fn new_class_ref(cp: Arc<ConstantPool>, class_info: &classfile::ConstantClassInfo) -> ClassRef {
        ClassRef {
            cp,
            class_name: class_info.get_name(),
            class: None
        }
    }

    pub fn new_class(cp: Arc<ConstantPool>, class: Arc<Class>) -> ClassRef {
        ClassRef {
            cp,
            class_name: class.get_name(),
            class: Some(class)
        }
    }
}
